﻿using System;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;

namespace WpfSocketCommunication
{
    public partial class WindowB : Window
    {
        private Socket _clientSocket;

        public WindowB()
        {
            InitializeComponent();
        }

        private void StartConnectingButton_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                _clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                IPEndPoint remoteEndPoint = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 8888);
                _clientSocket.Connect(remoteEndPoint);
                Task.Run(() => ReceiveMessages(CancellationToken.None));
            }
            catch (Exception ex)
            {
                MessageBox.Show($"连接出错: {ex.Message}");
            }
        }

        private void DisconnectButton_Click(object sender, RoutedEventArgs e)
        {
            _clientSocket?.Close();
            ReceivedMessagesListBox.Items.Clear();
        }

        private async void ReceiveMessages(CancellationToken cancellationToken)
        {
            try
            {
                byte[] buffer = new byte[1024];
                while (_clientSocket.Connected)
                {
                    int bytesRead = await ReceiveAsync(_clientSocket, buffer, 0, buffer.Length, SocketFlags.None, cancellationToken);
                    if (bytesRead > 0)
                    {
                        string message = Encoding.UTF8.GetString(buffer, 0, bytesRead);
                        Dispatcher.Invoke(() => ReceivedMessagesListBox.Items.Add(message));
                    }
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show($"接收消息出错: {ex.Message}");
            }
        }

        private async Task<int> ReceiveAsync(Socket socket, byte[] buffer, int offset, int size, SocketFlags socketFlags, CancellationToken cancellationToken)
        {
            var tcs = new TaskCompletionSource<int>();
            using (cancellationToken.Register(() => tcs.TrySetCanceled()))
            {
                socket.BeginReceive(buffer, offset, size, socketFlags, asyncResult =>
                {
                    try
                    {
                        int bytesRead = socket.EndReceive(asyncResult);
                        tcs.TrySetResult(bytesRead);
                    }
                    catch (Exception ex)
                    {
                        tcs.TrySetException(ex);
                    }
                }, null);
                return await tcs.Task;
            }
        }

        private void SendMessageButton_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                string message = MessageTextBox.Text;
                if (!string.IsNullOrEmpty(message))
                {
                    byte[] buffer = Encoding.UTF8.GetBytes(message);
                    _clientSocket.Send(buffer);
                    MessageTextBox.Clear();
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show($"发送消息出错: {ex.Message}");
            }
        }
    }
}